
local skynet = require "skynet"
local ex_cluster = require "ex_cluster"
local ex_log = require "ex_log"
local ex_event = require "ex_event"

local CMD = {}
local uinmap = {}
local MOD_CLASS

local attach_player_fn
local detach_player_fn
local init_fn

local function check_save_db()
    skynet.timeout(500, check_save_db)
    local now = os.time()
    for k, v in pairs(uinmap) do
        local mod = v.mod
        skynet.fork(function()
            mod:check_save()
        end)
    end
end


function CMD.attach_player(uin, param)
    local player = uinmap[uin]
    if not player then
        player = {
            uin = uin,
        }
        uinmap[uin] = player
        mod = MOD_CLASS({ player = player }, "player")
        mod.init()
        player.mod = mod
        player.event = ex_event()
    end
    if attach_player_fn then
        attach_player_fn(player, param)
    end
end

function CMD.detach_player(uin)
    local player = uinmap[uin]
    if player then
        player.mod:check_save()
        uinmap[uin] = nil
        if detach_player_fn then
            detach_player_fn(player)
        end
    end
end

function CMD.init(param)
    if init_fn then
        init_fn(CMD, param)
    end
    check_save_db()
end

function CMD.get_player(uin)
    return uinmap[uin]
end

return function(param)
    attach_player_fn = param.attach_player_fn
    detach_player_fn = param.detach_player_fn
    init_fn          = param.init_fn
    MOD_CLASS        = require(param.mod_class)
    skynet.start(function()
        skynet.dispatch("lua", function(session, source, cmd, ...)
            local f = CMD[cmd]
            assert(f, cmd)
            skynet.retpack(f(...))
        end)
    end)

end
